//
//  NSObject+Runtime.m
//  高仿暴走斗图
//
//  Created by huangsongyao on 16/3/7.
//  Copyright © 2016年 huangsongyao. All rights reserved.
//

#import "NSObject+Runtime.h"
#import <objc/runtime.h>

@implementation NSObject (Runtime)

- (void)checkObjectPropertyWithInfo:(id)info classes:(Class)classes {
    
    unsigned int count = 0;
    Ivar *ivars = class_copyIvarList(classes, &count);
    for (int i = 0; i<count; i++) {
        
        Ivar ivar = ivars[i];                   // 取出i位置对应的成员变量
        id temp = object_getIvar(info, ivar);   //根据实例对象截取对应属性值
        if (!temp) {
            object_setIvar(info, ivar, @"NONE");//如果对象为空，则手动设置对象
        }
    }
    free(ivars);
}

- (NSMutableArray *)getObjectAllPropertyWithInfo:(id)info {
    
    unsigned int count = 0;
    Class classes = [info class];
    NSMutableArray *propertys = [[NSMutableArray alloc] init];
    Ivar *ivars = class_copyIvarList(classes, &count);
    
    for (int i = 0; i<count; i++) {
        Ivar ivar = ivars[i];
        id temp = object_getIvar(info, ivar);
        if (temp) {
            [propertys addObject:temp];
        }
    }
    free(ivars);
    return propertys;
}

+ (Class)getObjectClassForInfo:(id)info {
    
    if (!info) {
        return [NSNull class];
    }
    Class classes = object_getClass(info);
    return classes;
}

- (NSMutableArray *)getPrivateAPIForClasses:(Class)classes {
    
    unsigned int count = 0;
    Method *memberMethods = class_copyMethodList(classes, &count);
    NSMutableArray *methods = [[NSMutableArray alloc] init];
    
    for (int i = 0; i < count; i++) {
        SEL name = method_getName(memberMethods[i]);
        NSString *methodName = [NSString stringWithCString:sel_getName(name) encoding:NSUTF8StringEncoding];
        [methods addObject:methodName];
        NSLog(@"member method:%@", methodName);
    }
    return methods;
}

- (SEL)getClassMethodForMethodName:(NSString *)methodName {
    
    return [NSObject getClassMethodForMethodName:methodName];
}

+ (SEL)getClassMethodForMethodName:(NSString *)methodName {
    
    return NSSelectorFromString(methodName);
}

+ (NSDictionary *)antiMappingObjectToDictionaryWithInfo:(id)info {
    
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    unsigned int propsCount;
    objc_property_t *props = class_copyPropertyList([info class], &propsCount);             //获得属性列表
    for(int i = 0;i < propsCount; i++) {
        
        objc_property_t prop = props[i];
        NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];        //获得属性的名称
        id value = [info valueForKey:propName];                                             //kvc读值
        if(value == nil) {
            value = [NSNull null];
        } else {
            value = [self antiMappingDictionaryToJsonWithInfo:value];                       //自定义处理数组，字典，其他类
        }
        [dic setObject:value forKey:propName];
    }
    return dic;
}

+ (id)antiMappingDictionaryToJsonWithInfo:(id)info {
    
    if([info isKindOfClass:[NSString class]] || [info isKindOfClass:[NSNumber class]] || [info isKindOfClass:[NSNull class]]) {
        return info;
    }
    if([info isKindOfClass:[NSArray class]]) {
        
        NSArray *objarr = info;
        NSMutableArray *arr = [NSMutableArray arrayWithCapacity:objarr.count];
        for(int i = 0;i < objarr.count; i++) {
            
            [arr setObject:[self antiMappingDictionaryToJsonWithInfo:[objarr objectAtIndex:i]] atIndexedSubscript:i];
        }
        return arr;
    }
    if([info isKindOfClass:[NSDictionary class]]) {
        
        NSDictionary *objdic = info;
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[objdic count]];
        for(NSString *key in objdic.allKeys) {
            [dic setObject:[self antiMappingDictionaryToJsonWithInfo:[objdic objectForKey:key]] forKey:key];
        }
        return dic;
    }
    return [self antiMappingObjectToDictionaryWithInfo:info];
}

- (void)method_exchangeImpForAction:(SEL)action anotherAction:(SEL)anoAction {
    
    [self method_exchangeImpForAction:action anotherAction:anoAction];
}

+ (void)method_exchangeImpForAction:(SEL)action anotherAction:(SEL)anoAction {
    
    Method method = class_getInstanceMethod(self, action);            //获取这个类的viewDidLoad方法,它的类型是一个objc_moethod结构体的指针
    Method anotherMethod = class_getInstanceMethod(self, anoAction);  //获取自定义的方法
    method_exchangeImplementations(method, anotherMethod);            //互换两个方法实现
}

+ (BOOL)addClassMethod:(SEL)aSEL methodName:(NSString *)name types:(const char *)types
{
    return class_addMethod(self.class, aSEL, method_getImplementation(class_getClassMethod(self.class, [NSObject getClassMethodForMethodName:name])), types);
}

+ (BOOL)addInstanceMethod:(SEL)aSEL methodName:(NSString *)name types:(const char *)types
{
    return class_addMethod(self.class, aSEL, method_getImplementation(class_getInstanceMethod(self.class, [NSObject getClassMethodForMethodName:name])), types);
}

@end
